/*
 * TMap Designer - A Thematic Map design software
 * Copyright (C) 2006 World Health Organization
 * http://www.who.int
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */
package who.tmap.dao.impl;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;

import org.jdom.Attribute;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;
import org.jdom.output.Format;
import org.jdom.output.XMLOutputter;

import who.tmap.bo.BizObject;
import who.tmap.bo.impl.BizObjectFactory;
import who.tmap.dao.DAO;
import who.tmap.dao.TMapDAOException;

/**
 * @author stl
 *
 * A base class for DAO
 */
public abstract class BaseDAOImpl implements DAO {

    protected BizObjectFactory bof =null;
    
    /**
     * Public visibility because CartographicDisplayDAO is in another package
     *
     */
    public BaseDAOImpl() {
        bof =BizObjectFactory.getInstance();
    }
    
    protected Element getRootElement( String fileName ) throws JDOMException, IOException {
        SAXBuilder builder = new SAXBuilder();

        builder.setIgnoringElementContentWhitespace(true);
        Document doc = builder.build(new File(fileName));
        
        Element rootElt =doc.getRootElement();
        
        return rootElt;
    }
    
    protected XMLOutputter getXMLOutputter() {
        XMLOutputter outputter =new XMLOutputter();
        Format format =Format.getPrettyFormat();
        format.setEncoding("UTF-8").setOmitDeclaration(false).setOmitEncoding(false);
        outputter.setFormat( format );      
        
        return outputter;
    }
    
    protected void writeXMLFile( String fileName, XMLOutputter outputter, Element rootElt ) throws IOException {
        Writer out = new BufferedWriter(new OutputStreamWriter(
                new FileOutputStream(fileName), "UTF8"));
        out.write(outputter.outputString( rootElt ));
        out.close();        
    }
       
    /**
     * Save a set of attributes as a xml file
     */
    public void save(String fileName, BizObject object) throws TMapDAOException {       

        try {
        	Element rootElt =saveXml( object );
            XMLOutputter outputter =getXMLOutputter();        	
            writeXMLFile( fileName, outputter, rootElt );
            object.setDirty( false );
        } catch (IOException e) {
            throw new TMapDAOException( e ); 
        }           	

    }  
    
    protected Element buildLinkedFileElt( String eltName, String fileName ) {
        Element elt =new Element( eltName );
        
        elt.setAttribute( "linkFile", fileName );
        
        return elt;
    }
    
    protected boolean isLinkedFile( Element elt ) {
	    return elt.getAttribute( "linkFile" ) != null; 
    }
    
    protected BizObject loadLinkedFile( Element elt ) throws TMapDAOException {
    	BizObject bo =null;
	    Attribute linkElt =elt.getAttribute( "linkFile" ); 
	    if ( linkElt != null ) {
	    	String fileName =linkElt.getValue();
	    	if ( fileName != null && !fileName.equals("") ) {
	    		bo =load( fileName );
	    		bo.setFile( new File(fileName) );
	    	}
	    }
	    
	    return bo;
    }

}
